﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Mail;
using System.Security.Cryptography.Pkcs;
using System.Security.Cryptography.X509Certificates;

namespace NHINDirect
{
    public class IncomingMessage : NHINDMessage
    {
        SignedCms m_signature;
        SignerInfo m_signer;
        NHINDAddressCollection m_domainRecipients;
        MailAddressCollection m_otherRecipients;        
        NHINDAddressCollection m_rejectedRecipients;
        
        public IncomingMessage()
        {
        }

        public override Header To
        {
            get
            {
                return base.To;
            }
            set
            {
                base.To = value;
                this.m_domainRecipients = null;
                this.m_otherRecipients = null;
            }
        }

        public NHINDAddressCollection DomainRecipients
        {
            get
            {
                if (this.m_domainRecipients == null)
                {
                    this.CategorizeRecipients(this.Agent.Domain);
                }

                return this.m_domainRecipients;
            }
        }

        public bool HasDomainRecipients
        {
            get
            {
                NHINDAddressCollection recipients = this.DomainRecipients;
                return (recipients != null && recipients.Count > 0);
            }
        }

        public MailAddressCollection OtherRecipients
        {
            get
            {
                if (this.m_otherRecipients == null)
                {
                    this.CategorizeRecipients(this.Agent.Domain);
                }

                return this.m_otherRecipients;
            }
        }

        public bool HasOtherRecipients
        {
            get
            {
                MailAddressCollection recipients = this.OtherRecipients;
                return (recipients != null && recipients.Count > 0);
            }
        }

        public NHINDAddressCollection RejectedRecipients
        {
            get
            {
                if (this.m_rejectedRecipients == null)
                {
                    this.m_rejectedRecipients = new NHINDAddressCollection();
                }

                return this.m_rejectedRecipients;
            }
        }

        public bool HasRejectedRecipients
        {
            get
            {
                return (this.m_rejectedRecipients != null && this.m_rejectedRecipients.Count > 0);
            }
        }
                
        public SignedCms Signature
        {
            get
            {
                return this.m_signature;
            }
            internal set
            {
                this.m_signature = value;
            }
        }

        public SignerInfo ValidatedSigner
        {
            get
            {
                return this.m_signer;
            }
            internal set
            {
                this.m_signer = value;
            }
        }

        public bool IsSignatureVerified
        {
            get
            {
                return (this.m_signer != null);
            }
        }

        /// <summary>
        /// Split "To" into recipients who are in this domain vs external
        /// </summary>
        /// <param name="domain"></param>
        internal void CategorizeRecipients(string domain)
        {
            if (string.IsNullOrEmpty(domain))
            {
                throw new ArgumentException();
            }
            MailAddressCollection to = this.ParsedTo;

            this.m_domainRecipients = new NHINDAddressCollection();
            this.m_otherRecipients = new MailAddressCollection();

            for (int i = 0, count = to.Count; i < count; ++i)
            {
                MailAddress address = to[i];
                if (address.DomainEquals(domain))
                {
                    this.m_domainRecipients.Add(new NHINDAddress(address));
                }
                else
                {
                    this.m_otherRecipients.Add(address);
                }
            }
        }

        internal void CategorizeRecipients(TrustEnforcementStatus minTrustStatus)
        {
            this.m_rejectedRecipients = NHINDAddressCollection.Create(this.DomainRecipients.GetUntrusted(minTrustStatus));
            this.DomainRecipients.RemoveUntrusted(minTrustStatus);
        }

        /// <summary>
        /// Combine the valid domain recipients & other recipients into a "To"
        /// </summary>
        internal void UpdateTo()
        {
            MailAddressCollection recipients = this.DomainRecipients.ToMailAddressCollection();
            recipients.Add(this.OtherRecipients);
            
            this.ParsedTo = recipients;
        }
    }
}
